package com.tom.architect02.ui10.day09;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Added by Tom on 2024/06/07.
 * 流式布局
 */
public class TagLayout extends ViewGroup {
    private List<List<View>> mChildViews = new ArrayList<>();
    private BaseAdapter mAdapter;

    public TagLayout(Context context) {
        this(context, null);
    }
    public TagLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mChildViews.clear(); // 清空集合
        int childCount = getChildCount();

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = getPaddingTop() + getPaddingBottom(); // 待计算的高度
        int lineWidth = getPaddingLeft(); // 一行的宽度

        ArrayList<View> childViews = new ArrayList(); // 一行中的元素
        mChildViews.add(childViews);
        int maxHeight = 0; // 子view高度不一致处理

        for (int i = 0; i < childCount; i++) {
            // 2.1 for循环测量子view，
            View childView = getChildAt(i);
            if (childView.getVisibility() == View.GONE) {
                continue; // 不可见，跳出循环。
            }
            // measureChild 执行后，可以获取View的宽高，因为会调用子view的onMeasure方法。
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            // 获取margin值 MarginLayoutParams, 参考LinearLayout 会复写，generate
            ViewGroup.MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();

            // 2.2 根据子view计算和指定自己的布局。
            // 一行不够时，需要换行。
            if (lineWidth + (childView.getMeasuredWidth() + params.leftMargin + params.rightMargin) > width) {
                // 换行,高度累加. 宽度重新赋值。
                lineWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin;
                childViews = new ArrayList<>(); // 重新new 一个List。
                mChildViews.add(childViews);

                height += maxHeight;
                maxHeight = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin;
            } else { // 不换行。
                lineWidth += childView.getMeasuredWidth() + params.leftMargin + params.rightMargin;
                maxHeight = Math.max(maxHeight, childView.getMeasuredHeight() + params.topMargin + params.bottomMargin);
            }
            childViews.add(childView);
        }

        height += maxHeight;
        // 设置自己的宽高
        setMeasuredDimension(width, height);
        Log.d("TAG", "w:" + width + " h:" + height + " lines:" + mChildViews.size());
    }

    @Override
    protected LayoutParams generateLayoutParams(LayoutParams p) {
        return super.generateLayoutParams(p);
    }
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left, top = getPaddingTop(), right, bottom;

        for (List<View> childViews : mChildViews) { // 摆放所有行
            left = getPaddingLeft(); // 换行
            int maxHeight = 0; // 一行的高度

            for (View childView : childViews) { // 摆放一行内所有元素。
                if (childView.getVisibility() == View.GONE) {
                    continue; // 不可见，跳出循环。
                }

                ViewGroup.MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams();
                left += params.leftMargin;
                int childTop = top + params.topMargin;

                right = left + childView.getMeasuredWidth();
                bottom = childTop + childView.getMeasuredHeight();
                // 摆放
                childView.layout(left, childTop, right, bottom);
                // left 累加
                left += childView.getMeasuredWidth() + params.rightMargin;

                maxHeight = Math.max(maxHeight, childView.getHeight() + params.topMargin + params.bottomMargin);
            }
            // top值累加，摆放下一行items
            top += maxHeight;
        }
    }

    // 设置适配器。
    public void setAdapter(BaseAdapter adapter) {
        if (adapter == null) {
            throw new IllegalArgumentException("adapter不能为空");
        }
        removeAllViews(); // 清空之前的子View。
        this.mAdapter = adapter;

        int childCount = mAdapter.getCount();
        for (int i = 0; i < childCount; i++) {
            View childView = mAdapter.getView(i, this);
            addView(childView);
        }
    }

}
